#!/bin/sh

########################################################################
# This test checks kedr_target_module_in_init() function.
# Usage: 
#   sh test.sh <in_init> <in_atomic>
#
# <in_init> specifies whether the call to the target function should be made
# at the initialization stage of the target module (!= 0) or from the module 
# core (== 0)
# <in_atomic> specifies whether that call should be made from atomic context
# (!= 0) or not (== 0).
########################################################################

# Just in case the tools like lsmod are not in their usual location.
export PATH=$PATH:/sbin:/bin:/usr/bin

########################################################################
# A function to check prerequisites: whether the necessary files exist,
# etc.
########################################################################
checkPrereqs()
{
    if test ! -f "${KEDR_MODULE}"; then
        printf "KEDR core module is missing: ${KEDR_MODULE}\n"
        exit 1
    fi
    
    if test ! -f "${TARGET_MODULE}"; then
        printf "Target module is missing: ${TARGET_MODULE}\n"
        exit 1
    fi
    
    if test ! -f "${PAYLOAD_MODULE}"; then
        printf "Payload module is missing: ${PAYLOAD_MODULE}\n"
        exit 1
    fi
}

########################################################################
# Cleanup function
########################################################################
cleanupAll()
{
    cd "${WORK_DIR}"
    
    lsmod | grep "${TARGET_NAME}" > /dev/null 2>&1
    if test $? -eq 0; then
        cd "${TARGET_NAME}"
        sh ./target_unload.sh
        cd "${WORK_DIR}"
    fi
    
    lsmod | grep "${PAYLOAD_NAME}" > /dev/null 2>&1
    if test $? -eq 0; then
        rmmod "${PAYLOAD_NAME}"
    fi
    
    lsmod | grep "@CORE_NAME@" > /dev/null 2>&1
    if test $? -eq 0; then
        rmmod "@CORE_NAME@"
    fi
}

########################################################################
# doTest() - preform the actual testing
########################################################################
doTest()
{
    insmod "${KEDR_MODULE}" target_name="${TARGET_NAME}" || exit 1

    insmod "${PAYLOAD_MODULE}"
    if test $? -ne 0; then
        printf "Failed to load the payload module\n"
        cleanupAll
        exit 1
    fi
    
    OUT_PARAM_FILE="/sys/module/${PAYLOAD_NAME}/parameters/target_in_init"
    if test ! -e "${OUT_PARAM_FILE}"; then
        printf "Parameter file does not exist: ${OUT_PARAM_FILE}\n"
        cleanupAll
        exit 1
    fi

    insmod "${TARGET_MODULE}" in_init=${IN_INIT} in_atomic=${IN_ATOMIC}
    if test $? -ne 0; then
        printf "Failed to load the target module: ${TARGET_MODULE}\n"
        cleanupAll
        exit 1
    fi

    rmmod "${TARGET_NAME}"
    if test $? -ne 0; then
        printf "Failed to unload the target module: ${TARGET_NAME}\n"
        cleanupAll
        exit 1
    fi

    # Save the result to be analyzed below
    RESULT_IN_INIT=$(cat "${OUT_PARAM_FILE}")

    rmmod "${PAYLOAD_NAME}"
    if test $? -ne 0; then
        printf "Failed to unload the payload module: ${PAYLOAD_NAME}\n"
        cleanupAll
        exit 1
    fi

    rmmod "@CORE_NAME@" || exit 1
    
    # Check the saved result
    printf "Expected value of target_in_init flag is '${IN_INIT}', "
    printf "actual value is '${RESULT_IN_INIT}'\n"
    if test "t${RESULT_IN_INIT}" != "t${IN_INIT}"; then
        exit 1
    fi
}

########################################################################
# main
########################################################################
WORK_DIR=${PWD}

if test $# -ne 2; then
    printf "Usage: sh test.sh <in_init> <in_atomic>\n"
    exit 1
fi

IN_INIT=$1
IN_ATOMIC=$2
printf "Mode: in_init=${IN_INIT}, in_atomic=${IN_ATOMIC}\n"

KEDR_MODULE="@CORE_DIR@/@CORE_NAME@.ko"

TARGET_NAME="test_in_init_target"
TARGET_MODULE="target/${TARGET_NAME}.ko"

PAYLOAD_NAME="test_in_init_payload"
PAYLOAD_MODULE="payload/${PAYLOAD_NAME}.ko"

checkPrereqs

printf "Kedr core module: ${KEDR_MODULE}\n"
printf "Target module: ${TARGET_MODULE}\n"
printf "Payload module: ${PAYLOAD_MODULE}\n"

doTest

# just in case
cleanupAll

# test passed
exit 0
